#!/usr/bin/env python3
"""
分支审查MCP工具
审查GitLab项目的分支命名规范
"""

import os
import asyncio
from typing import Dict, Any
from urllib.parse import urlparse

from gitlab import Gitlab
from biz.cmd.func.branch import BranchReviewFunc


class BranchReviewTool:
    """
    分支审查工具
    审查GitLab项目的分支命名规范
    """
    
    def __init__(self):
        self.branch_func = None
    
    def _get_branch_func(self):
        """延迟初始化分支审查功能"""
        if self.branch_func is None:
            self.branch_func = BranchReviewFunc()
        return self.branch_func
    
    def parse_gitlab_url(self, url: str) -> tuple[str, str]:
        """
        解析GitLab URL，提取gitlab_url和project_id
        """
        parsed_url = urlparse(url)
        
        if not parsed_url.scheme or not parsed_url.netloc:
            raise ValueError("无效的GitLab项目URL，请确保URL格式正确")
        
        gitlab_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
        
        # 提取项目路径
        path = parsed_url.path.strip('/')
        if path.endswith('.git'):
            path = path[:-4]
        
        return gitlab_url, path
    
    def get_branches_info(self, gitlab_url: str, project_id: str, access_token: str = None) -> str:
        """
        获取项目的分支信息
        """
        token = access_token or os.getenv("GITLAB_ACCESS_TOKEN")
        if not token:
            raise ValueError("未提供GitLab访问令牌，请设置GITLAB_ACCESS_TOKEN环境变量或传入access_token参数")
        
        try:
            gl = Gitlab(gitlab_url, private_token=token)
            project = gl.projects.get(project_id, lazy=True)
            
            # 获取所有分支
            branches = project.branches.list(all=True)
            
            if not branches:
                return "该项目没有分支"
            
            branches_text = f"项目分支列表 (共 {len(branches)} 个分支):\n\n"
            
            for branch in branches:
                branches_text += f"### 分支: {branch.name}\n"
                branches_text += f"- 最后提交: {branch.commit['id'][:8]}\n"
                branches_text += f"- 提交者: {branch.commit.get('author_name', 'Unknown')}\n"
                branches_text += f"- 提交时间: {branch.commit.get('created_at', 'Unknown')}\n"
                branches_text += f"- 提交信息: {branch.commit.get('message', 'No message')[:100]}...\n\n"
            
            return branches_text
            
        except Exception as e:
            raise ValueError(f"获取分支信息失败: {str(e)}")
    
    def get_review_prompts(self, branches_text: str) -> list[dict[str, str]]:
        """
        生成分支审查的提示词
        """
        system_prompt = """
你是一位资深的软件架构师，本次任务是对一个代码库的分支名称进行审查，具体要求如下：

### 具体要求：
1. **命名规范一致性**: 分支命名是否符合团队或项目定义的命名规范；是否遵循统一的命名风格（如小写字母、连字符分隔等）
2. **分支命名的可读性**: 分支名称是否能够清晰地表达其目的或功能；是否使用了容易引起混淆的缩写或术语
3. **分支命名的功能性**: 分支名称是否能够准确描述其实现的功能或修复的问题；是否与相关的任务、需求或问题关联
4. **分支命名的唯一性**: 分支名称是否与现有分支重复或过于相似；对于临时分支，是否包含时间戳或唯一标识以避免冲突
5. **分支命名的长度**: 分支名称是否过长，导致难以阅读或操作；是否在描述清晰的前提下尽量保持简短
6. **分支命名的类型化**: 是否使用了合适的前缀来区分分支类型；分支类型是否与其实际用途一致

### 常见的分支命名规范：
- **feature/**: 新功能开发分支
- **bugfix/** 或 **fix/**: 错误修复分支
- **hotfix/**: 紧急修复分支
- **release/**: 发布准备分支
- **develop**: 开发主分支
- **main/master**: 主分支

### 输出格式：
请按照以下Markdown格式输出review结果：

## 分支命名规范审查报告

### 📋 分支概览
[总结分支数量和主要类型]

### ✅ 优点
[列出分支命名的优点]

### ⚠️ 潜在问题
[指出分支命名中可能存在的问题]

#### 🔴 严重问题
[需要立即修复的命名问题]

#### 🟡 改进建议
[可以优化的命名方式]

### 📊 评分
- 命名规范一致性: X/10
- 可读性: X/10
- 功能性描述: X/10
- 唯一性: X/10
- 长度适中性: X/10
- 类型化规范: X/10

**总分: XX/60**

### 🎯 改进建议
[提供具体的优化建议]
"""
        
        user_prompt = f"""
请审查以下项目的分支命名规范：

{branches_text}
"""
        
        return [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt}
        ]
    
    async def execute(self, arguments: Dict[str, Any]) -> str:
        """
        执行分支审查
        """
        try:
            gitlab_url = arguments.get("gitlab_url")
            access_token = arguments.get("access_token")
            
            if not gitlab_url:
                return "错误: 缺少必需参数 gitlab_url"
            
            # 解析GitLab URL
            parsed_gitlab_url, project_id = self.parse_gitlab_url(gitlab_url)
            
            # 获取分支信息
            branches_text = self.get_branches_info(parsed_gitlab_url, project_id, access_token)
            
            if not branches_text or "该项目没有分支" in branches_text:
                return "该项目没有分支，无需审查"
            
            # 生成提示词并调用LLM
            messages = self.get_review_prompts(branches_text)
            
            # 异步调用LLM
            loop = asyncio.get_event_loop()
            branch_func = self._get_branch_func()
            review_result = await loop.run_in_executor(
                None, 
                branch_func.call_llm, 
                messages
            )
            
            # 清理结果格式
            if review_result.startswith("```markdown") and review_result.endswith("```"):
                review_result = review_result[11:-3].strip()
            
            return review_result
            
        except Exception as e:
            return f"分支审查执行失败: {str(e)}"